package com.hujing.io;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

/**
 * 进行io练习
 */
public class IODemo {

    // 2G 对应的字节数：2 * 1024MB * 1024KB = 2147483648 字节
    private static final long TWO_GIGABYTES = 2L * 1024 * 1024 * 1024;
    private static final int BLOCK_SIZE = 1024 * 1024;
    private static final int BUFFER_SIZE = 1024 * 8;//8K大小

    public static void main(String[] args) throws IOException {
//        readFile();
//        copyFile();
//        writeBigFile();
        readBigFile();
    }

    public static void readBigFile() {
        // 利用流式进行大文件的读取，这种方式的问题是文件如果没有换行符，会一次性将文件读取到内存中，可能会导致OOM
//        try(Stream<String> lines = Files.lines(Paths.get("F:\\project\\spring-parent\\io\\src\\main\\resources\\log.txt"))){
//            lines.forEach(System.out::println);
//        }catch (IOException e){
//            e.printStackTrace();
//        }

        try (BufferedReader br = new BufferedReader(new FileReader("F:\\project\\spring-parent\\io\\src\\main\\resources\\log.txt"))){
            char[] buffer = new char[BUFFER_SIZE];
            int len;
            while((len = br.read(buffer)) != -1){
                String chunk = new String(buffer, 0, len);
                System.out.println(chunk);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    public static void writeBigFile() throws IOException {
        File file = new File("F:\\project\\spring-parent\\io\\src\\main\\resources\\log.txt");
        // 获取文件大小
        if (!file.exists()) {
            file.createNewFile();
        }

        // 用字节流写入（无缓冲，直接写入磁盘，适合大文件）
        try (FileOutputStream fos = new FileOutputStream(file)) {
            long remainingBytes = TWO_GIGABYTES;
            String content = "这是一段日志，用来进行大文件测试这是一段日志，用来进行大文件测试这是一段日志，用来进行大文件测试这是一段日志，用来进行大文件测试";
            byte[] contentBytes = content.getBytes("UTF-8");
            while (remainingBytes > 0) {
                // 计算本次写入的字节数
                int writeSize = (int) Math.min(remainingBytes, contentBytes.length);
                // 写入内容
                fos.write(contentBytes, 0, writeSize);
                remainingBytes -= writeSize;

                // 进度打印
                long writtenBytes = TWO_GIGABYTES - remainingBytes;
                double progress = (writtenBytes * 100.0) / TWO_GIGABYTES;
                System.out.printf("写入进度：%.2f%%\n", progress);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void copyFile() {
        File file = new File("F:\\project\\spring-parent\\io\\src\\main\\resources\\知识搜索.txt");
        if (!file.exists()) {
            System.out.println("文件不存在");
        }

        try (FileInputStream fis = new FileInputStream(file);
             FileOutputStream fos = new FileOutputStream("F:\\project\\spring-parent\\io\\src\\main\\resources\\知识搜索3.txt")) {
            // 一个一个字节的读取
//            int len = 0;
//            while ((len = fis.read()) != -1) {
//                fos.write(len);
//            }
            // 批量读取
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
            System.out.println("文件拷贝成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void readFile() {
        File file = new File("F:\\project\\spring-parent\\io\\src\\main\\resources\\知识搜索.txt");
        if (!file.exists()) {
            System.out.println("文件不存在");
        }

//        // 读取文件内容-按行读取
//        try (FileInputStream fis = new FileInputStream(file);
//             InputStreamReader reader = new InputStreamReader(fis, "UTF-8");
//             BufferedReader br = new BufferedReader(reader)) {
//            String line;
//            while ((line = br.readLine()) != null) {
//                System.out.println(line);
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
